/*
 * player_mgr.h
 *
 *  Created on: Oct 28, 2013
 *      Author: killerg
 */

#ifndef PLAYER_MGR_H_
#define PLAYER_MGR_H_

#include "share/db_mgr.h"
#include "share/cs_msg.pb.h"
#include "share/patterns.h"
using namespace cs;


struct player_t;

typedef std::weak_ptr<player_t> wp_player_t;
typedef std::shared_ptr<player_t> sp_player_t;

typedef std::function<void(sp_player_t)> load_cb_t;
typedef std::function<void(db_error_t)> conn_new_cb_t;

struct simple_player_info_t {
    int64_t playerid;              // 序列号
    string name;                   // 名字
    EPlayerSex sex;                // 性别
    int32_t total_combat_force;    // 战力
    int32_t medal;                 // 勋章等级
    int32_t equip_level;           // 装备等级
};

inline void fill_osimpleplayerinfo(const simple_player_info_t* info, OSimplePlayerInfo* oinfo) {
    oinfo->set_playerid(info->playerid);    // 序列号
    oinfo->set_name(info->name);
    oinfo->set_sex(info->sex);
    oinfo->set_total_combat_force(info->total_combat_force);
    oinfo->set_medal(info->medal);
    oinfo->set_equip_level(info->equip_level);
}

struct player_mgr {

    struct stub_t {
        int64_t id;                             // 玩家id
        sp_player_t player;                     // 玩家指针
        std::list<load_cb_t> load_cb_list;     // 读取回调
        conn_new_cb_t create_cb;                 // 创建回调
        int32_t load_stamp = 0;
    };

    sp_player_t get_player(int64_t id) {
        auto op = stubs.get(id);
        if (NULL == op)
            return NULL;

        return op->player;
    }

    bool player_load(int64_t playeridid, load_cb_t cb);
    bool player_create(int64_t id, const string &name, EPlayerSex sex, const string &account, conn_new_cb_t cb);

    bool init();
    void destroy();
    void update();

    std::unordered_map<std::string, int64_t> name_table;
    std::unordered_set<std::string> name_creating;
    ptr_map<int64_t, simple_player_info_t*, std::unordered_map<int64_t, simple_player_info_t*> > infos;
    ptr_map<int64_t, stub_t*, std::unordered_map<int64_t, stub_t*> > stubs;

    std::queue<sp_player_t> save_queue;
    void update_save_queue(int num = -1);
    int saving = 0;

    int max_player = 0;
};

#endif /* PLAYER_MGR_H_ */
